package com.miukoo.aikao.qmanage.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.miukoo.aikao.core.dtos.*;
import com.miukoo.aikao.core.exceptions.ApiException;
import com.miukoo.aikao.core.types.TypeInterfaceManager;
import com.miukoo.aikao.qmanage.api.v1.QuestionApi;
import com.miukoo.aikao.qmanage.dto.export.QuestionExportDto;
import com.miukoo.aikao.qmanage.dto.request.QuestionQueryReqDto;
import com.miukoo.aikao.qmanage.mapper.QuestionMapper;
import com.miukoo.aikao.core.pojos.Question;
import com.miukoo.aikao.qmanage.service.QuestionAnswerService;
import com.miukoo.aikao.qmanage.service.QuestionService;
import com.miukoo.aikao.qmanage.service.RepositoryQuestionService;
import com.miukoo.aikao.qmanage.service.RepositoryService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * <p>
 * 语言设置 服务实现类
 * </p>
 *
 * @author 聪明笨狗
 * @since 2020-05-25 10:17
 */
@Service
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements QuestionService, QuestionApi {

    @Autowired
    private QuestionAnswerService questionAnswerService;

    @Autowired
    private RepositoryQuestionService repositoryQuestionService;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private TypeInterfaceManager typeInterfaceManager;

    @Override
    public PageResDto<List<QuestionDto>> paging(PageReqDto<QuestionQueryReqDto> reqDto) {
        //创建分页对象
        Page page = new Page<>(reqDto.getCurrent(), reqDto.getSize());
        //转换结果
        IPage<QuestionDto> pageData = baseMapper.paging(page, reqDto.getParams());
        return PageResDto.result(pageData.getTotal(),pageData.getRecords());
    }

    @Override
    public Question findById(Long id) {
        return this.getById(id);
    }

    @Override
    public List<Question> listByRandom(Long repoId, Short type, Short level, List<String> excludes, Short size) {
        return baseMapper.listByRandom(repoId, type, level, excludes, size);
    }

    @Override
    public QuestionDetailDto detail(Long id) {
        QuestionDetailDto respDto = new QuestionDetailDto();
        Question qu = this.getById(id);
        BeanUtils.copyProperties(qu,respDto);

        List<QuestionAnswerDto> answerList = questionAnswerService.listByQuestion(id);
        respDto.setAnswerList(answerList);

        List<String> repoIds = repositoryQuestionService.listByQuestion(id);
        respDto.setRepoIds(repoIds);

        return respDto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(QuestionDetailDto reqDto) {
        // 校验数据
        this.checkData(reqDto, "");
        Question qu = new Question();
        BeanUtils.copyProperties(reqDto,qu);
        // 更新
        this.saveOrUpdate(qu);

        // 保存全部问题
        questionAnswerService.saveAll(qu.getId(), reqDto.getAnswerList());

        // 保存到题库
        repositoryQuestionService.saveAll(qu.getId(), qu.getType(), reqDto.getRepoIds());
    }


    @Override
    public List<QuestionExportDto> listForExport(QuestionQueryReqDto query) {
        return baseMapper.listForExport(query);
    }

    @Override
    public int importExcel(List<QuestionExportDto> dtoList) {

        //根据题目名称分组
        Map<Integer, List<QuestionExportDto>> anMap = new HashMap<>(16);

        //题目本体信息
        Map<Integer, QuestionExportDto> quMap = new HashMap<>(16);

        //数据分组
        for (QuestionExportDto item : dtoList) {

            // 空白的ID
            if (StringUtils.isEmpty(item.getNo())) {
                continue;
            }

            Integer key;
            //序号
            try {
                key = Integer.parseInt(item.getNo());
            } catch (Exception e) {
                continue;
            }

            //如果已经有题目了，直接处理选项
            if (anMap.containsKey(key)) {
                anMap.get(key).add(item);
            } else {
                //如果没有，将题目内容和选项一起
                List<QuestionExportDto> subList = new ArrayList<>();
                subList.add(item);
                anMap.put(key, subList);
                quMap.put(key, item);
            }
        }

        int count = 0;
        try {
            //循环题目插入
            for (Integer key : quMap.keySet()) {

                QuestionExportDto im = quMap.get(key);

                //题目基本信息
                QuestionDetailDto qu = new QuestionDetailDto();
                qu.setContent(im.getQContent());
                qu.setAnalysis(im.getQAnalysis());
                qu.setType(Short.parseShort(im.getType()));
                qu.setCreateTime(new Date());

                //设置回答列表
                List<QuestionAnswerDto> answerList = this.processAnswerList(anMap.get(key));
                //设置题目
                qu.setAnswerList(answerList);
                //设置引用题库
                qu.setRepoIds(im.getRepoList());
                // 保存答案
                this.save(qu);
                count++;
            }

        } catch (ApiException e) {
            e.printStackTrace();
            throw new ApiException(1, "导入出现问题，行：" + count + "，" + e.getMessage());
        }
        return count;
    }

    /**
     * 处理回答列表
     *
     * @param importList
     * @return
     */
    private List<QuestionAnswerDto> processAnswerList(List<QuestionExportDto> importList) {
        List<QuestionAnswerDto> list = new ArrayList<>(16);
        for (QuestionExportDto item : importList) {
            QuestionAnswerDto a = new QuestionAnswerDto();
            a.setIsRight(item.getAIsRight().equals("1"));
            a.setContent(item.getAContent());
            a.setAnalysis(item.getAAnalysis());
            list.add(a);
        }
        return list;
    }

    /**
     * 校验题目信息
     *
     * @param qu
     * @param no
     * @throws Exception
     */
    public void checkData(QuestionDetailDto qu, String no) {
        if (StringUtils.isEmpty(qu.getContent())) {
            throw new ApiException(1, no + "题目内容不能为空！");
        }
        if (CollectionUtils.isEmpty(qu.getRepoIds())) {
            throw new ApiException(1, no + "至少要选择一个题库！");
        }
        typeInterfaceManager.saveCkeck(qu);
    }
}
